cmake_minimum_required(VERSION 3.12)
project(Lite)

set(BUILD_LITE "on")
add_compile_definitions(BUILD_LITE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/secure_option.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/compile_link_option.cmake)

#Options that can be configured through environment variables or manually
set(MSLITE_GPU_BACKEND "" CACHE STRING "enable gpu backend, \
    opencl only support arm64 and x86_64 , tensorrt only support x86_64, opencl/cuda/tensorrt/off")
set(MSLITE_REGISTRY_DEVICE "off" CACHE STRING "Compile Mindspore Lite that supports specific devices, \
    currently supported devices: Hi3516D/Hi3519A/Hi3559A/SD3403")
set(MSLITE_MICRO_PLATFORM "auto" CACHE STRING "Platform of micro static library micro static, \
    currently supported : cortex-m7/cortex-m4/cortex-m33/auto")
set(MSLITE_MINDDATA_IMPLEMENT "full" CACHE STRING "minddata mode, \
    currently supported : off/full/wrapper/lite/lite_cv")
option(MSLITE_ENABLE_NPU "enable npu, only arm64 or arm32 support" off)
option(MSLITE_ENABLE_COREML "enable coreML, only apple ios devices support" off)
option(MSLITE_ENABLE_NNAPI "enable nnapi, only android with arm64 or arm32" off)
option(MSLITE_ENABLE_TRAIN "enable train" on)
option(MSLITE_ENABLE_SSE "enable SSE instruction set, only x86_64 support" off)
option(MSLITE_ENABLE_AVX "enable AVX instruction set, only x86_64 support" off)
option(MSLITE_ENABLE_AVX512 "enable AVX512 instruction set, only x86_64 support" off)
option(MSLITE_ENABLE_CONVERTER "enable converter" on)
option(MSLITE_ENABLE_TOOLS "enable tools" on)
option(MSLITE_ENABLE_TESTCASES "enable testcase" off)
option(MSLITE_ENABLE_RUNTIME_PASS "enable runtime pass" on)
option(MSLITE_ENABLE_HIGH_PERFORMANCE "enable high performance" off)
option(MSLITE_ENABLE_STRING_KERNEL "enable string kernel" on)
option(MSLITE_ENABLE_CONTROLFLOW "enable control and tensorlist" on)
option(MSLITE_ENABLE_AUTO_PARALLEL "enable automatic parallelism" on)
option(MSLITE_ENABLE_WEIGHT_DECODE "enable weight decode" on)
option(MSLITE_ENABLE_CUSTOM_KERNEL "enable extend kernel registry" on)
option(MSLITE_ENABLE_MINDRT "enable mindrt use" on)
option(MSLITE_ENABLE_DELEGATE "enable delegate use" on)
option(MSLITE_ENABLE_FP16 "Whether to compile Fp16 operator" off)
option(MSLITE_ENABLE_INT8 "Whether to compile Int8 operator" on)
option(MSLITE_ENABLE_ACL "enable ACL" off)
option(MSLITE_ENABLE_ACL_QUANT_PARAM "enable ACL_QUANT_PARAM" off)
option(MSLITE_ENABLE_MODEL_ENCRYPTION "enable model encryption" off)
option(MSLITE_ENABLE_SPARSE_COMPUTE "enable sparse kernel" off)
option(MSLITE_ENABLE_RUNTIME_CONVERT "enable runtime convert" off)
option(MSLITE_ENABLE_RUNTIME_GLOG "enable runtime glog" off)
option(MSLITE_ENABLE_COVERAGE "enable code coverage" off)
option(MSLITE_ENABLE_SERVER_INFERENCE "enable inference on server" off)
option(MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE "enable distribute thread dynamically" off)
option(MSLITE_ENABLE_BFC_MEMORY "enable distribute BFC memory" off)
option(MSLITE_ENABLE_PARALLEL_INFERENCE "enable parallel inference interface" off)
option(MSLITE_ENABLE_SHARING_MODEL_WEIGHT "enable sharing model weight" off)
option(MSLITE_ENABLE_GRAPH_KERNEL "enable graph kernel" off)
option(MSLITE_ENABLE_CONVERT_PYTORCH_MODEL "enable to convert pytorch model" off)
option(MSLITE_ENABLE_KERNEL_EXECUTOR "enable kernel executor" off)
option(MSLITE_ENABLE_GITEE_MIRROR "enable download third_party from gitee mirror" off)
option(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE "enable cloud and device fusion inference architecture" off)
option(MSLITE_ENABLE_CLOUD_INFERENCE "alias to MSLITE_ENABLE_CLOUD_FUSION_INFERENCE" off)
option(MSLITE_ENABLE_MODEL_OBF "enable model obfuscation" off)
option(MSLITE_ENABLE_MODEL_PRE_INFERENCE "enable model do pre-inference when Build interface is called" off)
option(MSLITE_EXPORT_COMPUTE_IR "export graph structure dotfile when debug mode" off)
option(MSLITE_ENABLE_PACKAGE_WHEEL "enable package python wheel" off)
option(MSLITE_ENABLE_OPENCV "enable opencv" on)
option(MSLITE_TARGET_SITEAI "target siteai" off)

#Option that can be configured through manually
option(ENABLE_VERBOSE "" off)
set(VERSION_STR "1.8.0" CACHE STRING "get from version")

add_definitions(-DVERSION_STR=\"${VERSION_STR}\")

string(REPLACE "/mindspore/lite" "" TOP_DIR ${CMAKE_CURRENT_SOURCE_DIR})

if(MACHINE_LINUX_ARM64)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+fp16")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+fp16")
endif()

if(DEFINED ENV{MSLITE_ENABLE_CLOUD_FUSION_INFERENCE})
    set(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE $ENV{MSLITE_ENABLE_CLOUD_FUSION_INFERENCE})
endif()

if(DEFINED ENV{MSLITE_ENABLE_CLOUD_INFERENCE})
    set(MSLITE_ENABLE_CLOUD_INFERENCE $ENV{MSLITE_ENABLE_CLOUD_INFERENCE})
endif()

if(DEFINED ENV{MSLITE_GPU_BACKEND})
    set(MSLITE_GPU_BACKEND $ENV{MSLITE_GPU_BACKEND})
endif()
if(DEFINED ENV{MSLITE_REGISTRY_DEVICE})
    set(MSLITE_REGISTRY_DEVICE $ENV{MSLITE_REGISTRY_DEVICE})
endif()
if(DEFINED ENV{MSLITE_MICRO_PLATFORM})
    set(MSLITE_MICRO_PLATFORM $ENV{MSLITE_MICRO_PLATFORM})
endif()
if(DEFINED ENV{MSLITE_ENABLE_NPU})
    set(MSLITE_ENABLE_NPU $ENV{MSLITE_ENABLE_NPU})
endif()
if(DEFINED ENV{MSLITE_ENABLE_COREML})
    set(MSLITE_ENABLE_COREML $ENV{MSLITE_ENABLE_COREML})
endif()
if(DEFINED ENV{MSLITE_ENABLE_NNAPI})
    set(MSLITE_ENABLE_NNAPI $ENV{MSLITE_ENABLE_NNAPI})
endif()
if(DEFINED ENV{MSLITE_ENABLE_TRAIN})
    set(MSLITE_ENABLE_TRAIN $ENV{MSLITE_ENABLE_TRAIN})
endif()

if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    set(MSLITE_ENABLE_TRAIN OFF)
endif()

if(DEFINED ENV{MSLITE_ENABLE_SERVER_INFERENCE})
    set(MSLITE_ENABLE_SERVER_INFERENCE $ENV{MSLITE_ENABLE_SERVER_INFERENCE})
endif()

if(MSLITE_ENABLE_SERVER_INFERENCE OR MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    set(MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE on)
    set(MSLITE_ENABLE_BFC_MEMORY on)
    set(MSLITE_ENABLE_PARALLEL_INFERENCE on)
    set(MSLITE_ENABLE_SHARING_MODEL_WEIGHT on)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
    set(MSLITE_ENABLE_AVX512 on)
    set(MSLITE_ENABLE_CAPTURE_SIGNALS off)
    set(MSLITE_ENABLE_PACKAGE_WHEEL on)
    add_compile_definitions(SERVER_INFERENCE)
endif()

if(DEFINED ENV{MSLITE_ENABLE_PACKAGE_WHEEL})
    set(MSLITE_ENABLE_PACKAGE_WHEEL $ENV{MSLITE_ENABLE_PACKAGE_WHEEL})
endif()

if(DEFINED ENV{MSLITE_ENABLE_CAPTURE_SIGNALS})
    set(MSLITE_ENABLE_CAPTURE_SIGNALS $ENV{MSLITE_ENABLE_CAPTURE_SIGNALS})
endif()

if(MSLITE_ENABLE_CAPTURE_SIGNALS)
    add_compile_definitions(CAPTURE_SIGNALS)
endif()
if(DEFINED ENV{MSLITE_ENABLE_SSE})
    set(MSLITE_ENABLE_SSE $ENV{MSLITE_ENABLE_SSE})
endif()
if(DEFINED ENV{MSLITE_ENABLE_AVX})
    set(MSLITE_ENABLE_AVX $ENV{MSLITE_ENABLE_AVX})
endif()
if(DEFINED ENV{MSLITE_ENABLE_AVX512})
    set(MSLITE_ENABLE_AVX512 $ENV{MSLITE_ENABLE_AVX512})
endif()
if(DEFINED ENV{MSLITE_ENABLE_CONVERTER})
    set(MSLITE_ENABLE_CONVERTER $ENV{MSLITE_ENABLE_CONVERTER})
endif()
if(DEFINED ENV{MSLITE_ENABLE_RUNTIME_CONVERT})
    set(MSLITE_ENABLE_RUNTIME_CONVERT $ENV{MSLITE_ENABLE_RUNTIME_CONVERT})
endif()
if(DEFINED ENV{ENABLE_AKG} AND NOT MSLITE_ENABLE_RUNTIME_CONVERT)
    set(MSLITE_ENABLE_GRAPH_KERNEL $ENV{ENABLE_AKG})
endif()
if(DEFINED ENV{MSLITE_ENABLE_TOOLS})
    set(MSLITE_ENABLE_TOOLS $ENV{MSLITE_ENABLE_TOOLS})
endif()
if(DEFINED ENV{MSLITE_ENABLE_TESTCASES})
    set(MSLITE_ENABLE_TESTCASES $ENV{MSLITE_ENABLE_TESTCASES})
endif()
if(DEFINED ENV{MSLITE_ENABLE_RUNTIME_PASS})
    set(MSLITE_ENABLE_RUNTIME_PASS $ENV{MSLITE_ENABLE_RUNTIME_PASS})
endif()
if(DEFINED ENV{MSLITE_ENABLE_HIGH_PERFORMANCE})
    set(MSLITE_ENABLE_HIGH_PERFORMANCE $ENV{MSLITE_ENABLE_HIGH_PERFORMANCE})
endif()
if(DEFINED ENV{MSLITE_ENABLE_STRING_KERNEL})
    set(MSLITE_ENABLE_STRING_KERNEL $ENV{MSLITE_ENABLE_STRING_KERNEL})
endif()
if(DEFINED ENV{MSLITE_ENABLE_CONTROLFLOW})
    set(MSLITE_ENABLE_CONTROLFLOW $ENV{MSLITE_ENABLE_CONTROLFLOW})
endif()
if(DEFINED ENV{MSLITE_ENABLE_AUTO_PARALLEL})
    set(MSLITE_ENABLE_AUTO_PARALLEL $ENV{MSLITE_ENABLE_AUTO_PARALLEL})
endif()
if(DEFINED ENV{MSLITE_ENABLE_WEIGHT_DECODE})
    set(MSLITE_ENABLE_WEIGHT_DECODE $ENV{MSLITE_ENABLE_WEIGHT_DECODE})
endif()
if(DEFINED ENV{MSLITE_ENABLE_CUSTOM_KERNEL})
    set(MSLITE_ENABLE_CUSTOM_KERNEL $ENV{MSLITE_ENABLE_CUSTOM_KERNEL})
endif()
if(DEFINED ENV{MSLITE_ENABLE_MINDRT})
    set(MSLITE_ENABLE_MINDRT $ENV{MSLITE_ENABLE_MINDRT})
endif()
if(DEFINED ENV{MSLITE_ENABLE_DELEGATE})
    set(MSLITE_ENABLE_DELEGATE $ENV{MSLITE_ENABLE_DELEGATE})
endif()
if(DEFINED ENV{MSLITE_ENABLE_FP16})
    set(MSLITE_ENABLE_FP16 $ENV{MSLITE_ENABLE_FP16})
endif()
if(DEFINED ENV{MSLITE_ENABLE_INT8})
    set(MSLITE_ENABLE_INT8 $ENV{MSLITE_ENABLE_INT8})
endif()
if(DEFINED ENV{MSLITE_ENABLE_SPARSE_COMPUTE})
    set(MSLITE_ENABLE_SPARSE_COMPUTE $ENV{MSLITE_ENABLE_SPARSE_COMPUTE})
endif()
if(DEFINED ENV{MSLITE_ENABLE_ACL})
    set(MSLITE_ENABLE_ACL $ENV{MSLITE_ENABLE_ACL})
endif()
if(DEFINED ENV{MSLITE_ASCEND_TARGET})
    set(MSLITE_ASCEND_TARGET $ENV{MSLITE_ASCEND_TARGET})
endif()


if(DEFINED ENV{MSLITE_ENABLE_ACL_QUANT_PARAM})
    set(MSLITE_ENABLE_ACL_QUANT_PARAM $ENV{MSLITE_ENABLE_ACL_QUANT_PARAM})
endif()
if(DEFINED ENV{MSLITE_ENABLE_OPENCV})
    set(MSLITE_ENABLE_OPENCV $ENV{MSLITE_ENABLE_OPENCV})
endif()
if(DEFINED ENV{MSLITE_MINDDATA_IMPLEMENT})
    set(MSLITE_MINDDATA_IMPLEMENT $ENV{MSLITE_MINDDATA_IMPLEMENT})
endif()
if(DEFINED ENV{MSLITE_TARGET_SITEAI})
    set(MSLITE_TARGET_SITEAI $ENV{MSLITE_TARGET_SITEAI})
endif()

if(MSLITE_TARGET_SITEAI)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/providers/siteai)
else()
    set(MSLITE_DEPS_CMSIS on)
endif()

if(DEFINED ENV{MSLITE_ENABLE_MODEL_ENCRYPTION})
    if((${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND PLATFORM_X86_64) OR (
        (PLATFORM_ARM64 OR PLATFORM_ARM32) AND (ANDROID_NDK_TOOLCHAIN_INCLUDED OR TARGET_AOS_ARM)))
        set(MSLITE_ENABLE_MODEL_ENCRYPTION $ENV{MSLITE_ENABLE_MODEL_ENCRYPTION})
    elseif(MSLITE_ENABLE_ACL)
        set(MSLITE_ENABLE_MODEL_ENCRYPTION $ENV{MSLITE_ENABLE_MODEL_ENCRYPTION})
    else()
        set(MSLITE_ENABLE_MODEL_ENCRYPTION OFF)
    endif()
endif()

if(DEFINED ENV{MSLITE_ENABLE_MODEL_PRE_INFERENCE})
    set(MSLITE_ENABLE_MODEL_PRE_INFERENCE $ENV{MSLITE_ENABLE_MODEL_PRE_INFERENCE})
endif()

if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    set(MSLITE_ENABLE_CONVERTER ON)
    set(MSLITE_ENABLE_TRAIN off)
endif()

if(DEFINED ENV{MSLITE_ENABLE_COVERAGE})
    set(MSLITE_ENABLE_COVERAGE $ENV{MSLITE_ENABLE_COVERAGE})
endif()

if(DEFINED ENV{MSLITE_ENABLE_SERVING})
    set(MSLITE_ENABLE_SERVING $ENV{MSLITE_ENABLE_SERVING})
endif()
if(DEFINED ENV{MSLITE_ENABLE_KERNEL_EXECUTOR})
    set(MSLITE_ENABLE_KERNEL_EXECUTOR $ENV{MSLITE_ENABLE_KERNEL_EXECUTOR})
endif()

if(DEFINED ENV{MSLITE_ENABLE_CONVERT_PYTORCH_MODEL} AND DEFINED ENV{LIB_TORCH_PATH})
    set(ENABLE_CONVERT_PYTORCH_MODEL $ENV{MSLITE_ENABLE_CONVERT_PYTORCH_MODEL})
    set(LIB_TORCH_PATH $ENV{LIB_TORCH_PATH})
endif()

if(DEFINED ENV{MSLITE_ENABLE_GITEE_MIRROR})
    set(MSLITE_ENABLE_GITEE_MIRROR $ENV{MSLITE_ENABLE_GITEE_MIRROR})
endif()

if(MSLITE_EXPORT_COMPUTE_IR)
    set(MSLITE_EXPORT_COMPUTE_IR $ENV{MSLITE_EXPORT_COMPUTE_IR})
    add_compile_definitions(ENABLE_DRAW)
endif()

if(MSLITE_ENABLE_GITEE_MIRROR)
    set(ENABLE_GITEE ON)
endif()

if(DEFINED ENV{ENABLE_FAST_HASH_TABLE})
    add_compile_definitions(ENABLE_FAST_HASH_TABLE)
    if(NOT MSLITE_TARGET_SITEAI)
        set(MSLITE_DEPS_ROBIN_HOOD_HASHING on)
    endif()
endif()

if(DEFINED ENV{MSLITE_ENABLE_MODEL_OBF})
    set(MSLITE_ENABLE_MODEL_OBF $ENV{MSLITE_ENABLE_MODEL_OBF})
endif()

if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    add_compile_definitions(ENABLE_CLOUD_FUSION_INFERENCE)
    add_compile_definitions(ENABLE_CLOUD_INFERENCE)
    add_compile_definitions(SUPPORT_GPU)
    add_compile_definitions(USE_GLOG)
endif()

if(MSLITE_ENABLE_ACL AND (MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE))
    set(PLATFORM_ARM32 off)
endif()

if(MACHINE_LINUX_ARM64)
    add_compile_definitions(MACHINE_LINUX_ARM64)
    add_compile_definitions(LINUX_RUNTIME)
endif()
if(PLATFORM_X86_64)
    add_compile_definitions(LINUX_RUNTIME)
endif()
if(PLATFORM_MCU)
    add_compile_definitions(ENABLE_MCU)
endif()
if(TOOLCHAIN_NAME STREQUAL "himix200")
    set(TARGET_HIMIX on)
    set(TARGET_HIMIX200 on)
    add_compile_definitions(SUPPORT_NNIE)
elseif(TOOLCHAIN_NAME STREQUAL "himix100")
    set(TARGET_HIMIX on)
    set(TARGET_HIMIX100 on)
    add_compile_definitions(SUPPORT_NNIE)
elseif(TOOLCHAIN_NAME STREQUAL "mix210")
    set(TARGET_MIX210 on)
    add_compile_definitions(SUPPORT_34XX)
elseif(TOOLCHAIN_NAME STREQUAL "ohos-lite")
    set(TARGET_OHOS_LITE on)
    SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
elseif(TOOLCHAIN_NAME STREQUAL "ohos")
    set(TARGET_OHOS on)
    add_compile_definitions(MS_COMPILE_OHOS)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument -Wno-c++17-extensions")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument -Wno-c++17-extensions")
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.0
        AND NOT TARGET_HIMIX AND NOT TARGET_MIX210)
    message(FATAL_ERROR "GCC version ${CMAKE_CXX_COMPILER_VERSION} must not be less than 7.3.0")
endif()

if(PLATFORM_ARM64)
    if(MSLITE_GPU_BACKEND STREQUAL "")
        set(MSLITE_GPU_BACKEND "opencl")
    endif()
    if((NOT MSLITE_GPU_BACKEND STREQUAL "opencl") AND (NOT MSLITE_GPU_BACKEND STREQUAL "off"))
        message("invalid MSLITE_GPU_BACKEND value ${MSLITE_GPU_BACKEND} for arm64, MSLITE_GPU_BACKEND is set to off.")
        set(MSLITE_GPU_BACKEND "off")
    endif()
elseif(PLATFORM_ARM32)
    if((NOT MSLITE_GPU_BACKEND STREQUAL "opencl") AND (NOT MSLITE_GPU_BACKEND STREQUAL "off") AND
    (NOT MSLITE_GPU_BACKEND STREQUAL ""))
        message("invalid MSLITE_GPU_BACKEND value ${MSLITE_GPU_BACKEND} for arm32, MSLITE_GPU_BACKEND is set to off.")
        set(MSLITE_GPU_BACKEND "off")
    endif()
elseif(WIN32)
#    set(MSLITE_GPU_BACKEND "off")
else()
    if(${MSLITE_REGISTRY_DEVICE}  STREQUAL "SD3403" AND (NOT MSLITE_ENABLE_ACL))
        set(MSLITE_ENABLE_DPICO_ATC_ADAPTER on)
        add_definitions(-DENABLE_LITE_DPICO)
    endif()
    if(MSLITE_GPU_BACKEND STREQUAL "")
        set(MSLITE_GPU_BACKEND "off")
    endif()
    if((NOT MSLITE_GPU_BACKEND STREQUAL "tensorrt") AND (NOT MSLITE_GPU_BACKEND STREQUAL "off") AND
    (NOT MSLITE_GPU_BACKEND STREQUAL "cuda") AND (NOT MSLITE_GPU_BACKEND STREQUAL "opencl"))
        message("invalid MSLITE_GPU_BACKEND value ${MSLITE_GPU_BACKEND} for x86_64, MSLITE_GPU_BACKEND is set to off.")
        set(MSLITE_GPU_BACKEND "off")
    endif()
endif()

if(PLATFORM_ARM64 OR PLATFORM_ARM32)
    set(PLATFORM_ARM "on")
    set(MSLITE_ENABLE_SSE off)
    set(MSLITE_ENABLE_AVX off)
    set(MSLITE_ENABLE_AVX512 off)
    if(NOT MACHINE_LINUX_ARM64)
        set(MSLITE_ENABLE_CONVERTER off)
    endif()
    if(MSLITE_ENABLE_SERVER_INFERENCE)
        set(MSLITE_ENABLE_RUNTIME_GLOG on)
    else()
        set(MSLITE_ENABLE_RUNTIME_GLOG off)
    endif()
    set(MSLITE_ENABLE_RUNTIME_CONVERT off)
#set for cross - compiling toolchain
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
else()
    set(MSLITE_ENABLE_NPU off)
endif()

if(NOT APPLE)
    set(MSLITE_ENABLE_COREML off)
endif()

if(WIN32)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
endif()

if(DEFINED ENV{MSLITE_ENABLE_RUNTIME_GLOG})
    set(MSLITE_ENABLE_RUNTIME_GLOG $ENV{MSLITE_ENABLE_RUNTIME_GLOG})
endif()

if(DEFINED ENV{MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE})
    set(MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE $ENV{MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE})
endif()
if(MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE)
    add_compile_definitions(DYNAMIC_THREAD_DISTRIBUTE)
endif()

if(DEFINED ENV{MSLITE_ENABLE_BFC_MEMORY})
    set(MSLITE_ENABLE_BFC_MEMORY $ENV{MSLITE_ENABLE_BFC_MEMORY})
endif()
if(MSLITE_ENABLE_BFC_MEMORY)
    add_compile_definitions(BFC_MEMORY)
endif()

if(DEFINED ENV{MSLITE_ENABLE_PARALLEL_INFERENCE})
    set(MSLITE_ENABLE_PARALLEL_INFERENCE $ENV{MSLITE_ENABLE_PARALLEL_INFERENCE})
endif()

if(MSLITE_ENABLE_PARALLEL_INFERENCE)
    add_compile_definitions(PARALLEL_INFERENCE)
endif()

if(DEFINED ENV{MSLITE_ENABLE_SHARING_MODEL_WEIGHT})
    set(MSLITE_ENABLE_SHARING_MODEL_WEIGHT $ENV{MSLITE_ENABLE_SHARING_MODEL_WEIGHT})
endif()
if(MSLITE_ENABLE_SHARING_MODEL_WEIGHT)
    add_compile_definitions(SHARING_MODEL_WEIGHT)
endif()

if(DEFINED ENV{MSLITE_ENABLE_MULTI_LAYOUT})
    set(MSLITE_ENABLE_MULTI_LAYOUT $ENV{MSLITE_ENABLE_MULTI_LAYOUT})
endif()

if(MSLITE_ENABLE_SSE OR MSLITE_ENABLE_AVX OR MSLITE_ENABLE_AVX512 OR WIN32)
    set(MSLITE_ENABLE_RUNTIME_CONVERT off)
endif()

if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
    set(MSLITE_ENABLE_TRAIN off)
    if(NOT MSLITE_MINDDATA_IMPLEMENT STREQUAL "off")
        add_compile_definitions(ENABLE_MINDDATA_PYTHON)
    endif()
endif()

if(MSLITE_ENABLE_TRAIN AND NOT MSLITE_ENABLE_WEIGHT_DECODE)
    message(FATAL_ERROR "If MSLITE_ENABLE_WEIGHT_DECODE use if configured as off, "
            "MSLITE_ENABLE_TRAIN must also be configured as off")
endif()

if(MSLITE_ENABLE_CONTROLFLOW AND NOT MSLITE_ENABLE_MINDRT)
    message(FATAL_ERROR "If MSLITE_ENABLE_MINDRT use if configured as off, "
            "MSLITE_ENABLE_CONTROLFLOW must also be configured as off")
endif()

if(MSLITE_ENABLE_RUNTIME_CONVERT)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
    set(MSLITE_ENABLE_CONVERTER on)
endif()

if(MSLITE_ENABLE_TRAIN)
    set(SUPPORT_TRAIN on)
endif()

if(MSLITE_ENABLE_NPU AND NOT (MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE))
    set(SUPPORT_NPU on)
    if(NOT PLATFORM_ARM)
        message(FATAL_ERROR "NPU only support platform arm.")
    endif()
    if(DEFINED ENV{HWHIAI_DDK})
        message("HWHIAI_DDK=$ENV{HWHIAI_DDK}")
    else()
        message(FATAL_ERROR "please set HWHIAI_DDK, example: export HWHIAI_DDK=/root/usr/hwhiai-ddk-100.510.010.010/")
    endif()
endif()

if(MSLITE_ENABLE_NNAPI)
    set(SUPPORT_NNAPI on)
    if(NOT PLATFORM_ARM OR TARGET_HIMIX OR TARGET_OHOS_LITE)
        message(FATAL_ERROR "NNAPI only support platform arm with android.")
    endif()
endif()

if(TARGET_HIMIX OR TARGET_OHOS_LITE)
  set(MSLITE_ENABLE_MINDRT off)
endif()

if(MSVC)
  set(MSLITE_ENABLE_CONVERTER off)
  if(MSLITE_ENABLE_RUNTIME_GLOG)
    add_definitions(-DNOMINMAX)
    add_definitions(-DNOGDI)
    set(MSLITE_DEPS_DIRENT on)
  endif()
endif()

if(MSLITE_GPU_BACKEND STREQUAL cuda)
    set(MSLITE_ENABLE_CONVERTER on)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
endif()

if(MSLITE_ENABLE_CONVERTER)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
    add_compile_definitions(ENABLE_CONVERTER)
endif()

if(MSLITE_ENABLE_KERNEL_EXECUTOR)
    set(MSLITE_ENABLE_RUNTIME_GLOG on)
endif()

if(MSLITE_ENABLE_FP16 AND PLATFORM_ARM32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 12.0)
        message(STATUS "If you want to build fp16 in arm82_a32, please use android nkd r21e or r22b!")
        set(MSLITE_ENABLE_FP16 off)
    endif()
endif()

if(MSLITE_ENABLE_MODEL_PRE_INFERENCE)
    add_compile_definitions(ENABLE_PRE_INFERENCE)
endif()

if(TARGET_AOS_ARM)
    if(TOOLCHAIN_NAME STREQUAL "gcc")
        add_compile_definitions(USE_AOS_GCC_TOOLCHAIN)
    endif()
    add_compile_definitions(ENABLE_AOS_ARM)
    if(MSLITE_ENABLE_MODEL_ENCRYPTION)
        add_compile_definitions(ENABLE_OPENSSL)
    endif()
endif()

message(STATUS "************MindSpore Lite Build Option:************")
message(STATUS "\tMSLITE_GPU_BACKEND                         = \t${MSLITE_GPU_BACKEND}")
message(STATUS "\tMSLITE_REGISTRY_DEVICE                     = \t${MSLITE_REGISTRY_DEVICE}")
message(STATUS "\tMSLITE_ENABLE_NPU                          = \t${MSLITE_ENABLE_NPU}")
message(STATUS "\tMSLITE_ENABLE_COREML                       = \t${MSLITE_ENABLE_COREML}")
message(STATUS "\tMSLITE_ENABLE_NNAPI                        = \t${MSLITE_ENABLE_NNAPI}")
message(STATUS "\tMSLITE_ENABLE_TRAIN                        = \t${MSLITE_ENABLE_TRAIN}")
message(STATUS "\tMSLITE_MICRO_PLATFORM                      = \t${MSLITE_MICRO_PLATFORM}")
message(STATUS "\tMSLITE_ENABLE_SSE                          = \t${MSLITE_ENABLE_SSE}")
message(STATUS "\tMSLITE_ENABLE_AVX                          = \t${MSLITE_ENABLE_AVX}")
message(STATUS "\tMSLITE_ENABLE_AVX512                       = \t${MSLITE_ENABLE_AVX512}")
message(STATUS "\tMSLITE_ENABLE_CONVERTER                    = \t${MSLITE_ENABLE_CONVERTER}")
message(STATUS "\tMSLITE_ENABLE_TOOLS                        = \t${MSLITE_ENABLE_TOOLS}")
message(STATUS "\tMSLITE_ENABLE_TESTCASES                    = \t${MSLITE_ENABLE_TESTCASES}")
message(STATUS "\tMSLITE_ENABLE_HIGH_PERFORMANCE             = \t${MSLITE_ENABLE_HIGH_PERFORMANCE}")
message(STATUS "\tMSLITE_ENABLE_RUNTIME_PASS                 = \t${MSLITE_ENABLE_RUNTIME_PASS}")
message(STATUS "\tMSLITE_ENABLE_STRING_KERNEL                = \t${MSLITE_ENABLE_STRING_KERNEL}")
message(STATUS "\tMSLITE_ENABLE_CONTROLFLOW                  = \t${MSLITE_ENABLE_CONTROLFLOW}")
message(STATUS "\tMSLITE_ENABLE_AUTO_PARALLEL                = \t${MSLITE_ENABLE_AUTO_PARALLEL}")
message(STATUS "\tMSLITE_ENABLE_WEIGHT_DECODE                = \t${MSLITE_ENABLE_WEIGHT_DECODE}")
message(STATUS "\tMSLITE_ENABLE_CUSTOM_KERNEL                = \t${MSLITE_ENABLE_CUSTOM_KERNEL}")
message(STATUS "\tMSLITE_ENABLE_MINDRT                       = \t${MSLITE_ENABLE_MINDRT}")
message(STATUS "\tMSLITE_MINDDATA_IMPLEMENT                  = \t${MSLITE_MINDDATA_IMPLEMENT}")
message(STATUS "\tMSLITE_ENABLE_DELEGATE                     = \t${MSLITE_ENABLE_DELEGATE}")
message(STATUS "\tMSLITE_ENABLE_ACL                          = \t${MSLITE_ENABLE_ACL}")
message(STATUS "\tMSLITE_ENABLE_FP16                         = \t${MSLITE_ENABLE_FP16}")
message(STATUS "\tMSLITE_ENABLE_INT8                         = \t${MSLITE_ENABLE_INT8}")
message(STATUS "\tMSLITE_ENABLE_MODEL_ENCRYPTION             = \t${MSLITE_ENABLE_MODEL_ENCRYPTION}")
message(STATUS "\tMSLITE_ENABLE_SPARSE_COMPUTE               = \t${MSLITE_ENABLE_SPARSE_COMPUTE}")
message(STATUS "\tMSLITE_ENABLE_RUNTIME_CONVERT              = \t${MSLITE_ENABLE_RUNTIME_CONVERT}")
message(STATUS "\tMSLITE_ENABLE_RUNTIME_GLOG                 = \t${MSLITE_ENABLE_RUNTIME_GLOG}")
message(STATUS "\tMSLITE_ENABLE_COVERAGE                     = \t${MSLITE_ENABLE_COVERAGE}")
message(STATUS "\tMSLITE_ENABLE_SERVER_INFERENCE             = \t${MSLITE_ENABLE_SERVER_INFERENCE}")
message(STATUS "\tMSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE    = \t${MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE}")
message(STATUS "\tMSLITE_ENABLE_BFC_MEMORY                   = \t${MSLITE_ENABLE_BFC_MEMORY}")
message(STATUS "\tMSLITE_ENABLE_PARALLEL_INFERENCE           = \t${MSLITE_ENABLE_PARALLEL_INFERENCE}")
message(STATUS "\tMSLITE_ENABLE_SHARING_MODEL_WEIGHT         = \t${MSLITE_ENABLE_SHARING_MODEL_WEIGHT}")
message(STATUS "\tMSLITE_ENABLE_GRAPH_KERNEL                 = \t${MSLITE_ENABLE_GRAPH_KERNEL}")
message(STATUS "\tMSLITE_ENABLE_KERNEL_EXECUTOR              = \t${MSLITE_ENABLE_KERNEL_EXECUTOR}")
message(STATUS "\tMSLITE_ENABLE_CLOUD_FUSION_INFERENCE       = \t${MSLITE_ENABLE_CLOUD_FUSION_INFERENCE}")
message(STATUS "\tMSLITE_ENABLE_CLOUD_INFERENCE              = \t${MSLITE_ENABLE_CLOUD_INFERENCE}")
message(STATUS "\tMSLITE_ENABLE_CAPTURE_SIGNALS              = \t${MSLITE_ENABLE_CAPTURE_SIGNALS}")
message(STATUS "\tMSLITE_ENABLE_MODEL_OBF                    = \t${MSLITE_ENABLE_MODEL_OBF}")
message(STATUS "\tMSLITE_ENABLE_MODEL_PRE_INFERENCE          = \t${MSLITE_ENABLE_MODEL_PRE_INFERENCE}")
message(STATUS "\tMSLITE_EXPORT_COMPUTE_IR                   = \t${MSLITE_EXPORT_COMPUTE_IR}")
message(STATUS "\tMSLITE_ENABLE_PACKAGE_WHEEL                = \t${MSLITE_ENABLE_PACKAGE_WHEEL}")
message(STATUS "\tMSLITE_ENABLE_OPENCV                       = \t${MSLITE_ENABLE_OPENCV}")
message(STATUS "\tMSLITE_TARGET_SITEAI                       = \t${MSLITE_TARGET_SITEAI}")

if((MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_TESTCASES) AND (
        NOT MSLITE_ENABLE_MINDRT
        OR NOT MSLITE_ENABLE_STRING_KERNEL
        OR NOT MSLITE_ENABLE_CONTROLFLOW
        OR NOT MSLITE_ENABLE_WEIGHT_DECODE
        OR NOT MSLITE_ENABLE_CUSTOM_KERNEL))
    message(FATAL_ERROR "If one of 'MSLITE_ENABLE_MINDRT MSLITE_ENABLE_STRING_KERNEL "
            "MSLITE_ENABLE_CONTROLFLOW MSLITE_ENABLE_WEIGHT_DECODE MSLITE_ENABLE_CUSTOM_KERNEL'"
            "is configured as off, MSLITE_ENABLE_CONVERTER and MSLITE_ENABLE_TESTCASES must also be configured as off")
endif()

if(((MSLITE_GPU_BACKEND STREQUAL tensorrt) OR MSLITE_ENABLE_NPU OR MSLITE_ENABLE_COREML OR MSLITE_ENABLE_NNAPI) AND (
        NOT MSLITE_ENABLE_DELEGATE))
    message(FATAL_ERROR "If MSLITE_ENABLE_DELEGATE use is configured as off, MSLITE_ENABLE_NPU and MSLITE_ENABLE_COREML
    and MSLITE_ENABLE_NNAPI must also be configured as off and MSLITE_GPU_BACKEND can not be configured as tensorrt.")
endif()

if(MSLITE_ENABLE_HIGH_PERFORMANCE)
    add_compile_definitions(ENABLE_HIGH_PERFORMANCE)
endif()

if(ENABLE_ASAN)
    add_definitions(-fsanitize=address -fno-omit-frame-pointer)
    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        add_definitions(-mllvm -asan-use-private-alias=1)
    endif()
    add_link_options(-fsanitize=address)
endif()

if(MSLITE_ENABLE_COVERAGE)
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -g --coverage -fprofile-arcs -ftest-coverage")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g --coverage -fprofile-arcs -ftest-coverage")
endif()

if(MSLITE_ENABLE_ACL)
    add_definitions(-D ENABLE_LITE_ACL)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-shlib-undefined")

    if(MSLITE_ENABLE_ACL_QUANT_PARAM)
        add_definitions(-D ENABLE_ACL_QUANT_PARAM)
    endif()
    if(DEFINED ENV{ASCEND_CUSTOM_PATH})
        set(ASCEND_PATH $ENV{ASCEND_CUSTOM_PATH})
    else()
        set(ASCEND_PATH /usr/local/Ascend)
    endif()
    if("${MSLITE_REGISTRY_DEVICE}" STREQUAL "SD3403")
        if(PLATFORM_ARM64)
            set(ASCEND_CANN_RUNTIME_PATH ${ASCEND_PATH}/ascend-toolkit/latest/arm64-lmixlinux200/lib64)
        elseif(PLATFORM_ARM32 OR WIN32)
            message(FATAL_ERROR "SD3403 compilation only supports x86 and arm64 platform")
        else()
            add_compile_definitions(SUPPORT_SD3403_DAVINCI)
            set(ASCEND_CANN_RUNTIME_PATH ${ASCEND_PATH}/ascend-toolkit/latest/x86_64-linux/lib64)
        endif()
    else()
        set(ASCEND_CANN_RUNTIME_PATH ${ASCEND_PATH}/latest/lib64)
        set(ASCEND_TOOLKIT_RUNTIME_PATH ${ASCEND_PATH}/ascend-toolkit/latest/lib64)
    endif()
endif()

set(PKG_NAME_PREFIX mindspore-lite-${VERSION_STR})

if(SUPPORT_NPU)
    set(DDK_PATH "$ENV{HWHIAI_DDK}/ddk/ai_ddk_lib")
    set(DDK_INCLUDE_PATH "$ENV{HWHIAI_DDK}/ddk/ai_ddk_lib/include")
    if(PLATFORM_ARM64)
        set(DDK_LIB_PATH ${DDK_PATH}/lib64)
    elseif(PLATFORM_ARM32)
        set(DDK_LIB_PATH ${DDK_PATH}/lib)
    endif()
    add_compile_definitions(SUPPORT_NPU)
endif()

add_compile_definitions(NO_DLIB)

if(NOT MSVC)
    add_compile_options(-fPIC)
endif()

if(PLATFORM_ARM64)
    if(TARGET_HIMIX100 OR TARGET_MIX210 OR MACHINE_LINUX_ARM64)
        set(RUNTIME_COMPONENT_NAME "linux-aarch64")
    elseif(TARGET_OHOS)
        set(RUNTIME_COMPONENT_NAME "ohos-aarch64")
    elseif(TARGET_AOS_ARM)
        set(RUNTIME_COMPONENT_NAME "aos-aarch64")
    else()
        set(RUNTIME_COMPONENT_NAME "android-aarch64")
    endif()
elseif(PLATFORM_ARM32)
    set(RUNTIME_COMPONENT_NAME "android-aarch32")
    if(TARGET_HIMIX200)
        set(RUNTIME_COMPONENT_NAME "linux-aarch32")
    elseif(TARGET_OHOS_LITE)
        set(RUNTIME_COMPONENT_NAME "ohos-aarch32")
    elseif(TARGET_OHOS)
        set(RUNTIME_COMPONENT_NAME "ohos-aarch32")
    endif()
elseif(WIN32)
    if(CMAKE_SIZEOF_VOID_P EQUAL 4)
        set(RUNTIME_COMPONENT_NAME "win-x86")
    else()
        set(RUNTIME_COMPONENT_NAME "win-x64")
    endif()
elseif(PLATFORM_MCU)
    set(RUNTIME_COMPONENT_NAME "none-${TOOLCHAIN_NAME}")
else()
    if((CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") AND MSLITE_ENABLE_ACL)
        set(RUNTIME_COMPONENT_NAME "linux-aarch64")
    else()
        set(RUNTIME_COMPONENT_NAME "linux-x64")
    endif()
endif()

set(LITE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(CORE_DIR ${TOP_DIR}/mindspore/core)
set(CCSRC_DIR ${TOP_DIR}/mindspore/ccsrc)
set(NNACL_DIR ${CCSRC_DIR}/plugin/device/cpu/kernel/nnacl)

if(PLATFORM_MCU)
    set(CMAKE_C_FLAGS  "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types")
#    set(MSLITE_DEPS_CMSIS on)
    add_subdirectory(${NNACL_DIR} build/nnacl)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/converter/micro/cmake/cortex-m/ build)
    include(${TOP_DIR}/cmake/package_lite.cmake)
    return()
endif()

include_directories(${TOP_DIR})
include_directories(${CORE_DIR})
include_directories(${CORE_DIR}/ir)
include_directories(${CCSRC_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/litert/kernel/cpu)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/)
include_directories(${TOP_DIR}/third_party)
include_directories(${CMAKE_BINARY_DIR})
include_directories(${CCSRC_DIR}/minddata/dataset)

include(${TOP_DIR}/cmake/utils.cmake)
include(${TOP_DIR}/cmake/dependency_utils.cmake)
include(${TOP_DIR}/cmake/dependency_securec.cmake)
include(${TOP_DIR}/cmake/graphengine_variables.cmake)

find_and_use_mold()

# include(${TOP_DIR}/cmake/external_libs/flatbuffers.cmake)
set(MSLITE_DEPS_FLATBUFFERS on)

if(MSLITE_GPU_BACKEND STREQUAL opencl)
    # include(${TOP_DIR}/cmake/external_libs/opencl.cmake)
    set(MSLITE_DEPS_OPENCL on)
endif()

function(find_required_package pkg_name)
    find_package(${pkg_name})
    if(NOT ${pkg_name}_FOUND)
        message(FATAL_ERROR "Required package ${pkg_name} not found, "
                "please install the package and try building MindSpore again.")
    endif()
endfunction()

if(MSLITE_ENABLE_COREML)
    if(PLATFORM_ARM32)
        message(FATAL_ERROR "CoreML not support arm32 platform!")
    endif()
    add_compile_definitions(ENABLE_COREML)
    find_required_package(Patch)
    include(${TOP_DIR}/cmake/external_libs/protobuf.cmake)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64")
    set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
    include(${TOP_DIR}/cmake/external_libs/protobuf_arm.cmake)
endif()

if(MSLITE_ENABLE_CONVERTER OR MSLITE_MINDDATA_IMPLEMENT STREQUAL "full" OR MSLITE_MINDDATA_IMPLEMENT STREQUAL "wrapper"
    OR MSLITE_ENABLE_TOOLS OR MSLITE_ENABLE_KERNEL_EXECUTOR)
    # include(${TOP_DIR}/cmake/external_libs/json.cmake)
    set(MSLITE_DEPS_JSON on)
endif()

if(DEFINED ARCHS)
    add_definitions(-DMS_COMPILE_IOS)
endif()

if(ENABLE_VERBOSE)
    set(CMAKE_VERBOSE_MAKEFILE on)
endif()
if(SUPPORT_TRAIN)
    add_compile_definitions(SUPPORT_TRAIN)
endif()
if(ENABLE_NEON)
    add_compile_definitions(ENABLE_NEON)
endif()

if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    if((${MSLITE_REGISTRY_DEVICE} STREQUAL "off") OR (${MSLITE_REGISTRY_DEVICE} STREQUAL "OFF"))
        set(ENABLE_GLIBCXX OFF)
    else()
        set(ENABLE_GLIBCXX ON)
    endif()
else()
    set(ENABLE_GLIBCXX ON)
endif()

if(MSLITE_GPU_BACKEND STREQUAL cuda)
    # add_definitions(-DGPU_CUDA)
    add_compile_definitions(SUPPORT_GPU)
    set(SUPPORT_CUDA on)
    if(DEFINED ENV{CUDA_HOME})
        message("CUDA_HOME = $ENV{CUDA_HOME}")
    else()
        message(FATAL_ERROR "please set CUDA_HOME, example: export CUDA_HOME=/usr/local/cuda-10.1/")
    endif()
    find_package(CUDAToolkit)
    if(NOT CUDAToolkit_FOUND)
        message(FATAL_ERROR "Required package CUDAToolkit not found, "
                "please install the package and try building MindSpore again.")
    endif()
    if((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND (${CUDAToolkit_VERSION} VERSION_GREATER "10.1.168"))
        set(ENABLE_GLIBCXX OFF)
    else()
        message(WARNING "Current CUDAToolkit version (${CUDAToolkit_VERSION}) is less than 10.1.168, "
                "might have unfixed issues with std string, set ENABLE_GLIBCXX = ON automatically to prevent errors. "
                "However, import mindspore and import mindspore_lite in Python API at the same time cannot be used, "
                "if you need to import them at the same time, the version higher than 10.1.168 is recommended.")
        set(ENABLE_GLIBCXX ON)
    endif()
endif()

if(MSLITE_GPU_BACKEND STREQUAL tensorrt)
    add_compile_definitions(SUPPORT_GPU)
    set(SUPPORT_TENSORRT on)
    if(DEFINED ENV{TENSORRT_PATH})
        message("TENSORRT_PATH = $ENV{TENSORRT_PATH}")
    else()
        message(FATAL_ERROR "please set TENSORRT_PATH, example: export TENSORRT_PATH=/root/usr/TensorRT-6.0.1.5/")
    endif()
    if(DEFINED ENV{CUDA_HOME})
        message("CUDA_HOME = $ENV{CUDA_HOME}")
    else()
        message(FATAL_ERROR "please set CUDA_HOME, example: export CUDA_HOME=/usr/local/cuda-10.1/")
    endif()
    find_package(CUDAToolkit)
    if(NOT CUDAToolkit_FOUND)
        message(FATAL_ERROR "Required package CUDAToolkit not found, "
                "please install the package and try building MindSpore again.")
    endif()
    if((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND (${CUDAToolkit_VERSION} VERSION_GREATER "10.1.168"))
        set(ENABLE_GLIBCXX OFF)
    else()
        message(WARNING "Current CUDAToolkit version (${CUDAToolkit_VERSION}) is less than 10.1.168, "
                "might have unfixed issues with std string, set ENABLE_GLIBCXX = ON automatically to prevent errors. "
                "However, import mindspore and import mindspore_lite in Python API at the same time cannot be used, "
                "if you need to import them at the same time, the version higher than 10.1.168 is recommended.")
        set(ENABLE_GLIBCXX ON)
    endif()
endif()

if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    if(NOT ENABLE_GLIBCXX)
        add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
    endif()
endif()

if(WIN32)
    add_compile_definitions(BUILDING_DLL)
    add_compile_definitions(BUILDING_CORE_DLL)
endif()

include_directories(${CORE_DIR}/mindrt/include)
include_directories(${CORE_DIR}/mindrt/src)

if(MSLITE_ENABLE_MODEL_OBF)
    if(PLATFORM_ARM32)
        set(OBF_LIB_DIR ${TOP_DIR}/mindspore/lite/tools/obfuscator/lib/android-aarch32)
    elseif(PLATFORM_ARM64)
        set(OBF_LIB_DIR ${TOP_DIR}/mindspore/lite/tools/obfuscator/lib/android-aarch64)
    else()
        set(OBF_LIB_DIR ${TOP_DIR}/mindspore/lite/tools/obfuscator/lib/linux-x64)
    endif()
    set(OBF_LIBS libmsdeobfuscator-lite.so)
endif()

if((MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_RUNTIME_GLOG))
    # include(${TOP_DIR}/cmake/external_libs/glog.cmake)
    set(MSLITE_DEPS_GLOG on)
endif()

if(MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_KERNEL_EXECUTOR)
    find_required_package(Patch)
    # include(${TOP_DIR}/cmake/external_libs/protobuf.cmake)
    set(MSLITE_DEPS_PROTOBUF on)
endif()

if(NOT APPLE)
    if(PLATFORM_X86_64 OR MACHINE_LINUX_ARM64)
        if(NOT MSLITE_TARGET_SITEAI)
            set(MSLITE_DEPS_PYBIND11 on)
        endif()
    endif()
endif()

if(MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    if(MSLITE_ENABLE_OPENCV)
        set(MSLITE_DEPS_OPENCV on)
        add_definitions(-DMSLITE_DEPS_OPENCV)
    endif()
    set(MSLITE_DEPS_EIGEN on)
endif()

if(NOT MSLITE_TARGET_SITEAI)
    set(MSLITE_DEPS_CMSIS on)
endif()

if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE)
    if(NOT MSLITE_TARGET_SITEAI)
        set(MSLITE_DEPS_MKLDNN on)
        set(MSLITE_DEPS_LIBEVENT on)
        set(MSLITE_DEPS_PYBIND11 on)
    endif()
    if(SUPPORT_TENSORRT)
        set(MSLITE_DEPS_FAST_TRANSFORMERS on)
        if(MSLITE_ENABLE_GRAPH_KERNEL)
            set(MSLITE_DEPS_AKG_TENSORRT on)
        endif()
    endif()
endif()

# In core/CMakelists, core link mindspore::crypto, and crypto need the OPENSSL lib,
# So before enter into core/CMakelists, you need to set MSLITE_DEPS_OPENSSL on to contain the OPENSSL lib,
# Such as when MSLITE_ENABLE_CONVERTER is on or MSLITE_ENABLE_KERNEL_EXECUTOR is on.
if((${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR APPLE) AND (
    MSLITE_ENABLE_CONVERTER OR (MSLITE_ENABLE_KERNEL_EXECUTOR AND NOT TARGET_AOS_ARM)))
    if(NOT MSLITE_TARGET_SITEAI)
        set(MSLITE_DEPS_OPENSSL on)
    endif()
endif()

if(MSLITE_ENABLE_MODEL_ENCRYPTION AND NOT TARGET_AOS_ARM)
    if(NOT MSLITE_TARGET_SITEAI)
        set(MSLITE_DEPS_OPENSSL on)
    endif()
    if(MSLITE_DEPS_OPENSSL)
        add_compile_definitions(ENABLE_OPENSSL)
    endif()
endif()

include(${LITE_DIR}/cmake/lite_dependences.cmake)

if(MSLITE_GPU_BACKEND STREQUAL opencl AND NOT (MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE))
    add_definitions(-DGPU_OPENCL)
    gene_opencl(${CMAKE_CURRENT_SOURCE_DIR}/src/litert/kernel/opencl/cl)
    gene_opencl(${CMAKE_CURRENT_SOURCE_DIR}/src/litert/kernel/opencl/cl/int8)
    add_definitions(-DUSE_OPENCL_WRAPPER)
    add_definitions(-DMS_OPENCL_PROFILE=false)
    add_definitions(-DCL_TARGET_OPENCL_VERSION=200)
    add_definitions(-DCL_HPP_TARGET_OPENCL_VERSION=120)
    add_definitions(-DCL_HPP_MINIMUM_OPENCL_VERSION=120)
    add_compile_definitions(SUPPORT_GPU)
    include_directories(${CMAKE_BINARY_DIR}/_deps/opencl-headers-src/)
    include_directories(${CMAKE_BINARY_DIR}/_deps/opencl-clhpp-src/include)
endif()

file(GLOB FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schema/*.fbs)

ms_build_flatbuffers_lite(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schema/ fbs_src ${CMAKE_BINARY_DIR}/schema "")
ms_build_flatbuffers_lite(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schema/ fbs_inner_src ${CMAKE_BINARY_DIR}/schema/inner
        "inner")

if(MSLITE_ENABLE_CONVERTER)
    # find_required_package(Patch)
    # include_directories(${PYTHON_INCLUDE_DIRS})
    # if(NOT ENABLE_CLOUD_AND_LITE)
    #     include(${TOP_DIR}/cmake/external_libs/opencv.cmake)
    #     include(${TOP_DIR}/cmake/external_libs/eigen.cmake)
    # endif()
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/converter)
endif()

if(NOT WIN32 AND NOT APPLE)
    if(MSLITE_ENABLE_MODEL_OBF)
        add_compile_definitions(ENABLE_MODEL_OBF)
    endif()
endif()

if(MSLITE_ENABLE_FP16)
    add_compile_definitions(ENABLE_FP16)
    if(PLATFORM_ARM32)
        add_compile_definitions(ENABLE_ARM82_A32)
    endif()
endif()

# if(MSLITE_ENABLE_MODEL_ENCRYPTION AND NOT ENABLE_CLOUD_AND_LITE)
#     find_required_package(Patch)
#     include(${TOP_DIR}/cmake/external_libs/openssl.cmake)
#     add_compile_definitions(ENABLE_OPENSSL)
# endif()

if(MSLITE_ENABLE_MINDRT)
    add_compile_definitions(ENABLE_MINDRT)
endif()

if(PLATFORM_ARM32)
    add_definitions(-mfloat-abi=softfp -mfpu=neon)
    add_compile_definitions(ENABLE_ARM32)
    add_compile_definitions(ENABLE_ARM)
endif()
if(PLATFORM_ARM64)
    add_compile_definitions(ENABLE_ARM64)
    add_compile_definitions(ENABLE_ARM)
endif()

if(NOT PLATFORM_ARM)
    if(MSLITE_ENABLE_AVX512)
        set(X86_64_SIMD "avx512")
        add_compile_definitions(ENABLE_SSE)
        add_compile_definitions(ENABLE_AVX)
        add_compile_definitions(ENABLE_AVX512)
    elseif(MSLITE_ENABLE_AVX)
        set(X86_64_SIMD "avx")
        add_compile_definitions(ENABLE_SSE)
        add_compile_definitions(ENABLE_AVX)
    elseif(MSLITE_ENABLE_SSE)
        set(X86_64_SIMD "sse")
        add_compile_definitions(ENABLE_SSE)
        if(NOT MSVC)
            set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.1")
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
        endif()
    endif()
endif()

if(MSLITE_MINDDATA_IMPLEMENT STREQUAL "lite" OR MSLITE_MINDDATA_IMPLEMENT STREQUAL "full"
    OR MSLITE_MINDDATA_IMPLEMENT STREQUAL "wrapper" OR MSLITE_MINDDATA_IMPLEMENT STREQUAL "lite_cv")
    add_compile_definitions(ENABLE_ANDROID)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/minddata)
endif()

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/common/ops)
if(ANDROID_NDK_TOOLCHAIN_INCLUDED OR TARGET_OHOS_LITE OR TARGET_HIMIX)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/converter/micro/coder)
endif()

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src)
add_subdirectory(${CCSRC_DIR}/plugin/device/cpu/kernel/nnacl build)

if(MSLITE_ENABLE_TOOLS)
    if(NOT MSLITE_COMPILE_TWICE)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/benchmark)
        if(TARGET_HIMIX)
            add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/converter/micro/providers/nnie nnie_micro)
        endif()
    endif()
    if(SUPPORT_TRAIN)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/benchmark_train)
    endif()
    if(NOT PLATFORM_ARM AND NOT WIN32 AND NOT (MSLITE_ENABLE_CLOUD_FUSION_INFERENCE OR MSLITE_ENABLE_CLOUD_INFERENCE))
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/cropper)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/schema_gen)
        add_dependencies(fbs_src gen_ops)
        add_dependencies(fbs_inner_src gen_ops)
    endif()
endif()

if(NOT WIN32 AND MSLITE_ENABLE_TESTCASES)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test)
endif()

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/kernel_builder)

if(NOT APPLE)
    include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/file_list.cmake)
    include(${TOP_DIR}/cmake/package_lite.cmake)

    if(MSLITE_ENABLE_PACKAGE_WHEEL)
        if(PLATFORM_X86_64 OR MACHINE_LINUX_ARM64)
            add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/python)
        endif()
    else()
        message("MSLITE_ENABLE_PACKAGE_WHEEL=${MSLITE_ENABLE_PACKAGE_WHEEL} will not package python wheel")
    endif()
endif()
